/*
 *  Copyright (C) 2010 GSyC/LibreSoft, Universidad Rey Juan Carlos.
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see http://www.gnu.org/licenses/. 
 *
 *  Author : Raúl Román López <rroman@gsyc.es>
 *
 */
package com.LibreGeoSocial.App.AR;

import java.util.ArrayList;

import android.app.Activity;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.preference.PreferenceManager;

import com.LibreGeoSocial.Api.Audio;
import com.LibreGeoSocial.Api.GeoNode;
import com.LibreGeoSocial.Api.Note;
import com.LibreGeoSocial.Api.Photo;
import com.LibreGeoSocial.Api.User;
import com.LibreGeoSocial.Api.Layers.GenericLayer;
import com.LibreGeoSocial.App.R;
import com.LibreGeoSocial.App.GeoNames.AltitudeManager;
import com.LibreGeoSocial.App.Utils.LocationUtils;


public class ARActivity extends Activity{
	
	private ARLayerManager layers;
	
	private ArrayList<ARGeoNode> resources_list = null;
	private GenericLayer mylayer = null;
	private float[] location = new float[3];  // designed for [latitude, longitude, altitude]
	private boolean is_threshold;
	private float threshold;
	private boolean use_height = true;
	
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        layers = new ARLayerManager(this);
        if(loadMainHeightPreference())
        	loadThresholdPreferences();
    }
    
    protected boolean loadMainHeightPreference(){
    	SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
		use_height = !sharedPreferences.getBoolean(ARPreferences.KEY_NOT_HEIGHT, false);
		return use_height;
    }
    
    protected void loadThresholdPreferences(){
		SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
		is_threshold = sharedPreferences.getBoolean(ARPreferences.KEY_IS_DIST_FILTER, false);
		threshold = Float.parseFloat(sharedPreferences.getString(ARPreferences.KEY_DIST_FILTER, "0"));
    }
    
    protected void setResourcesList(ArrayList<ARGeoNode> resources_list){
    	this.resources_list = resources_list;
    }
    
    protected void setMyLayer(GenericLayer mylayer){
    	this.mylayer = mylayer;
    }
    
    protected void useHeight(boolean use_height){
    	this.use_height = use_height;
    }
    
    protected boolean isUsingHeight(){
    	return use_height;
    }
    
    protected ArrayList<ARGeoNode> getResourcesList(){
    	return resources_list;
    }
    
    protected GenericLayer getMyLayer(){
    	return mylayer;
    }
    
    protected void setLocation(float[] location){
    	this.location = location.clone();
    }
    
    protected float[] getLocation(){
    	return location;
    }
    
    protected ARLayerManager getLayers(){
    	return layers;
    }
    
    protected void updateHeights(){
    	int length = resources_list.size();
    	for(int i = (length - 1); i > -1; i--){
    		GeoNode resource = resources_list.get(i).getGeoNode();
    		if(resource.getAltitude() < 0)
    			resource.setAltitude((float)AltitudeManager.getAltitudeFromLatLong(
    					(float)(double)resource.getLatitude(), 
    					(float)(double)resource.getLongitude()));
    	}
    }
    
	protected void refreshResourceDrawns(float[] values){
//		boolean isclicked = is_clicked;

		if(resources_list==null)
			return;
		if(resources_list.isEmpty())
			return;

		int sizeList = resources_list.size();

		ARGeoNode resource;
		for(int i=sizeList; i>0; i--){
			resource = resources_list.get(i-1);
			
			if(resource == null)
				return;
			
			float distance = resource.distanceToResource(location);
			float res_azimuth = resource.azimuthToResource(location);
			float azimuth_user = LocationUtils.calculateAzimuthFromUser(ARCompassManager.getAzimuth(values),res_azimuth);

			float[] resource_loc = {(float)(double)resource.getGeoNode().getLatitude(), (float)(double)resource.getGeoNode().getLongitude()};
			float azimuth_camera = LocationUtils.calculateAngleToCam(location, resource_loc, ARCompassManager.getAzimuth(values), azimuth_user, LocationUtils.DEV_DISTANCE);


			float res_roll;
			if(!use_height || (is_threshold && (distance > threshold)))
				res_roll = 90;
			else
				res_roll = resource.rollToResource(resource.distanceToResource(location));

			float elevation = LocationUtils.calculateRollFromUser(ARCompassManager.getElevation(values), res_roll);

			if (!resource.isLoaded()){
				//Initialize the draw element
				String name = "Unamed";
				Bitmap icon = null;
				if ( Photo.class.isInstance(resource.getGeoNode()))    	
				{
					Photo node = (Photo) resource.getGeoNode();
					name = node.getName();
					icon = BitmapFactory.decodeResource(getResources(), R.drawable.camera_38);
				}
				else if ( Note.class.isInstance(resource.getGeoNode()) )
				{
					Note node = (Note) resource.getGeoNode();
					name = node.getTitle();
					icon = BitmapFactory.decodeResource(getResources(), R.drawable.paper_pencil_48);
				}
				else if ( User.class.isInstance(resource.getGeoNode()) )
				{
					User node = (User) resource.getGeoNode();
					name = node.getUsername();
					icon = BitmapFactory.decodeResource(getResources(), R.drawable.user_48);
				}
				else if ( Audio.class.isInstance(resource.getGeoNode()) )
				{
					Audio node = (Audio) resource.getGeoNode();
					name = node.getName();
					icon = BitmapFactory.decodeResource(getResources(), R.drawable.audio_48); 
				}

				resource.createDrawn(this, name, icon);

			}

			resource.setDrawnValues(azimuth_camera, res_azimuth, elevation, distance);

			//FIXME opengl things
			//        		cubeList.addListElem(i-1, azimuth_camera, elevation, distance);
			/////////////////////
			if(!resource.isLoaded()){
				resource.setLoaded(true);
			}

			if(!layers.isChildInResourcesList(resource.getDrawn()))
				layers.addResourceElement(resource.getDrawn(), null);
			resource.invalidateDrawn();

		}
		//FIXME opengl
		//			opengl.requestRender();
		//////////////
	}
}